﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SGS.Cards;
using SGS.Standard.Delegate;
using SGS.Standard.Actor;
using SGS.Standard.EventArgs;
using SGS.Standard.CardSelector;

namespace SGS.Standard.GameLogic
{
    public class Core : GameLogicBase
    {
        #region 游戏基础逻辑
        public static void GL_Heal(Player from, Player target, int count = 1)
        {
            if (target.GameInfo.CurrentHP < target.GameInfo.MaxHP)
            {
                target.GameInfo.CurrentHP++;
                RaiseNoticeMessageEvent("{0} 回复{1}点体力", target.PlayerName, count);
            }
        }

        public static void GL_Damage(Player from, Player target, DamageType damageType = DamageType.Default, List<Card> cards = null, int damageHP = 1)
        {
            if (damageType != DamageType.Lost)
            {
                SGS.Standard.GameLogic.EventCaller.GL_OnDamaging(from, target);

                target.GameInfo.CurrentHP -= damageHP;
                RaiseNoticeMessageEvent("{1} 受到 {2} 点{3}伤害 ( 来自 {0} )", from.PlayerName, target.PlayerName, damageHP, damageType);
                CheckPlayerDeadForHelp(target);

                if (damageType != DamageType.Lost)
                {
                    SGS.Standard.GameLogic.EventCaller.GL_AfterDamage(from, target, cards);
                }

                // TODO：发动伤害后事件，
                // 如发动奸雄cards对象清空
            }
            else
            {
                RaiseNoticeMessageEvent("{0} 失去{1}点体力", target.PlayerName, damageHP);
                target.GameInfo.CurrentHP -= damageHP;
                CheckPlayerDeadForHelp(target);
            }
        }

        internal static void GL_Judge(Player judgePlayer, JudgeCallback callback, string reason = "")
        {
            var c = CurrentGameContext.CardHeap.GetCard();

            RaiseNoticeMessageEvent("{0}-{1}的判定结果为{2}", judgePlayer.PlayerName, reason, c);

            // 判定生效前，用于“鬼道”，“鬼才”
            // GL_OnPreJudgeEffect(); 

            bool needDiscard = true;

            // 判定生效，用于“天妒”
            // GL_OnJudgeEffect(); 
            // needDiscard = false;

            // 判定生效后事件
            callback(judgePlayer, c);

            // 判定执行完毕弃置
            if (needDiscard)
            {
                GL_Discard(judgePlayer, c.AsList());
            }
        }

        /// <summary>
        /// 弃牌
        /// </summary>
        /// <param name="from"></param>
        /// <param name="cards"></param>
        internal static List<Card> GL_Discard(Player from, IEnumerable<Card> cards)
        {
            if (from == null)
            {
                RaiseNoticeMessageEvent("无主弃牌：{0}", string.Join(",", cards.Select(p => p.ToString()).ToArray()));
            }
            else
            {
                RaiseNoticeMessageEvent("{0} 弃牌：{1}", from.PlayerName, string.Join(",", cards.Select(p => p.ToString()).ToArray()));
                // TODO 发动落英
            }

            CurrentGameContext.CardHeap.DiscardsHeap.PushToEnd(cards);

            // 只返回真正进入弃牌堆的牌
            return cards.ToList();
        }

        /// <summary>
        /// 使用后的将牌仍至牌堆，不算弃牌，算用掉的
        /// </summary>
        /// <param name="from"></param>
        /// <param name="cards"></param>
        internal static void GL_UsedDiscard(Player from, IEnumerable<Card> cards)
        {
            //if (from == null)
            //{
            //    RaiseNoticeMessageEvent("无主弃牌：{0}", string.Join(",", cards.Select(p => p.ToString()).ToArray()));
            //}
            //else
            //{
            //    RaiseNoticeMessageEvent("{0} 弃牌：{1}", from.PlayerName, string.Join(",", cards.Select(p => p.ToString()).ToArray()));
            //    // TODO 发动落英
            //}

            CurrentGameContext.CardHeap.DiscardsHeap.PushToEnd(cards);

            // 只返回真正进入弃牌堆的牌
            // return cards.ToList();
        }

        internal static bool GL_Used(Player from, IEnumerable<Card> cards, bool checkEmptyCard = false)
        {
            if (cards == null || checkEmptyCard && cards.Count() == 0)
            {
                // 卡检测不通过
                return false;
            }

            if (!from.GameInfo.HasCard(cards))
            {
                // 卡检测不通过
                return false;
            }

            from.GameInfo.TryRemoveCard(cards);

            CurrentGameContext.CardHeap.DiscardsHeap.PushToEnd(cards);
            return true;
        }

        internal static void GL_SetPlayerDead(Player deadPlayer, Player murder = null)
        {
            RaiseNoticeMessageEvent("{0}死亡", deadPlayer.PlayerName);

            deadPlayer.GameInfo.Live = false;
            List<Card> ownCard = deadPlayer.GameInfo.RemoveAllCardWithoutEvent();
            List<Card> judgeCard = deadPlayer.GameInfo.RemoveJudgeCard();

            // TODO : 发动行喪

            // 弃牌
            GL_Discard(null, judgeCard);
            GL_Discard(deadPlayer, ownCard);

            // 来源执行奖惩
        }

        internal static void CheckPlayerDeadForHelp(Player p, Player murder = null)
        {
            if (p.GameInfo.CurrentHP >= 1)
            {
                return;
            }

            var node = CurrentGameContext.PlayersCircle.GetCircleNode(CurrentGameContext.CurrentPlayer);
            var dummy = node.Previous;

            bool startNotAsk = true;

            while (dummy.Next != node || startNotAsk)
            {
                dummy = dummy.Next;
                if (startNotAsk)
                {
                    startNotAsk = false;
                }

                if (!dummy.Value.GameInfo.Live)
                {
                    continue;
                }
                else
                {
                    // TODO 触发技能：补益

                    // 此处修正成每次出一个桃，若出了桃则在结算完毕后再次出桃
                    while (true)
                    {
                        var result = Ask.GL_AskPeach(p, dummy.Value, 1 - p.GameInfo.CurrentHP);
                        if (result.AnswerResult == AskUseCardResult.AskResult.Used)
                        {
                            SGS.Standard.GameLogic.Basic.GL_Peach(dummy.Value, p);
                            GL_UsedDiscard(dummy.Value, result.UsedCard);

                            // 血超过上线后，跳出
                            if (p.GameInfo.CurrentHP > 0)
                            {
                                RaiseNoticeMessageEvent("{0}脱离濒死状态", p.PlayerName);
                                return;
                            }
                        }
                        else
                        {
                            // case AskUseCardResultEx.AskUseCardResult.Cancel:
                            // case AskUseCardResultEx.AskUseCardResult.Skip:
                            break;
                        }
                    }

                }
            }

            GL_SetPlayerDead(p, murder);
        }

        internal static List<Card> PlayerDealCards(Player p, int cnt = 1)
        {
            List<Card> cards = GameContext.Current.CardHeap.GetCards(cnt);
            p.GameInfo.OwnCards.PushToEnd(cards);
            RaiseNoticeMessageEvent("{0}从牌堆里摸取了{1}张牌", p.PlayerName, cnt);
            return cards;
        }
        #endregion
    }
}
